

package com.maoshi.shop.platform.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.maoshi.shop.bean.model.User;
import com.maoshi.shop.common.util.PageParam;
import com.maoshi.shop.common.util.RedisUtil;
import com.maoshi.shop.security.comment.constants.SecurityConstants;
import com.maoshi.shop.security.comment.model.AppConnect;
import com.maoshi.shop.security.comment.service.AppConnectService;
import com.maoshi.shop.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;


/**
 * @author lgh on 2018/10/16.
 */
@RestController
@RequestMapping("/admin/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private AppConnectService appConnectService;

    @Autowired
    private TokenStore tokenStore;

    /**
     * 分页获取
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('plateform:user:page')")
    public ResponseEntity<IPage<User>> page(User user,PageParam<User> page) {
//        IPage<User> userPage = userService.page(page, new LambdaQueryWrapper<User>()
//                .like(StrUtil.isNotBlank(user.getNickName()), User::getNickName, user.getNickName())
//                .eq(user.getStatus() != null, User::getStatus, user.getStatus())
//                .isNotNull(User::getNickName)
//                .orderByDesc(User::getUserRegtime));
        IPage<User> userPage =  userService.getUserPage(page,user);
//        for (User userResult : userPage.getRecords()) {
//            userResult.setNickName(userResult.getNickName());
//        }
        return ResponseEntity.ok(userPage);
    }

    /**
     * 获取信息
     */
    @GetMapping("/info/{userId}")
    @PreAuthorize("@pms.hasPermission('plateform:user:info')")
    public ResponseEntity<User> info(@PathVariable("userId") String userId) {
        User user = userService.getById(userId);
        user.setNickName(user.getNickName());
        return ResponseEntity.ok(user);
    }

    /**
     * 修改
     */
    @PutMapping
    @PreAuthorize("@pms.hasPermission('plateform:user:update')")
    public ResponseEntity<Void> update(@RequestBody User user) {
        user.setModifyTime(new Date());
        user.setNickName(user.getNickName());
        userService.updateById(user);

        List<AppConnect> appConnects = appConnectService.list(new LambdaQueryWrapper<AppConnect>().eq(AppConnect::getUserId, user.getUserId()));
        for (AppConnect appConnect : appConnects) {
            // 移除登录成功的验证缓存
            Map<String, String> values = new LinkedHashMap<>();
            values.put("username", appConnect.getAppId() + StrUtil.COLON + appConnect.getBizUserId());
            values.put("client_id", "null");
            values.put("scope", "");
            String key = SecurityConstants.YAMI_OAUTH_PREFIX + "auth_to_access:" + generateKey(values);
            RedisUtil.del(key);
            // 移除token校验的缓存
            Collection<OAuth2AccessToken> tokens = tokenStore.findTokensByClientIdAndUserName(StrUtil.NULL, appConnect.getAppId() + StrUtil.COLON + appConnect.getBizUserId());
            for (OAuth2AccessToken token : tokens) {
                RedisUtil.del(SecurityConstants.YAMI_OAUTH_PREFIX + "access:" + token.getValue());
            }
        }

        return ResponseEntity.ok().build();
    }



    private String generateKey(Map<String, String> values) {
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
            byte[] bytes = digest.digest(values.toString().getBytes(StandardCharsets.UTF_8));
            return String.format("%032x", new BigInteger(1, bytes));
        } catch (NoSuchAlgorithmException nsae) {
            throw new IllegalStateException("MD5 algorithm not available.  Fatal (should be in the JDK).", nsae);
        }
    }

}
